package formatter

import (
	"fmt"
	"testing"
)

func TestPerRangeFormatterDefaultPercent(t *testing.T) {
	tests := []struct {
		input    any
		expected string
	}{
		// integers
		{999_999_999 / 100., "1.0B%"},
		{12_345_789 / 100., "12.3M%"},
		{2_345_789 / 100., "2.3M%"},
		{999_999 / 100., "1.0M%"},
		{345_789 / 100., "345.8k%"},
		{45_789 / 100., "45.8k%"},
		{5_789 / 100., "5.8k%"},
		{999 / 100., "999%"},
		{789 / 100., "789%"},
		{89 / 100., "89%"},
		{9 / 100., "9%"},
		{0 / 100., "0%"},
		{-0 / 100., "0%"},
		{-999_999_999 / 100., "-1.0B%"},
		{-12_345_789 / 100., "-12.3M%"},
		{-2_345_789 / 100., "-2.3M%"},
		{-999_999 / 100., "-1.0M%"},
		{-345_789 / 100., "-345.8k%"},
		{-45_789 / 100., "-45.8k%"},
		{-5_789 / 100., "-5.8k%"},
		{-999 / 100., "-999%"},
		{-789 / 100., "-789%"},
		{-89 / 100., "-89%"},
		{-9 / 100., "-9%"},

		// non integers
		{999_999_999.1234686 / 100., "1.0B%"},
		{12_345_789.1234686 / 100., "12.3M%"},
		{2_345_789.1234686 / 100., "2.3M%"},
		{999_999.4397 / 100., "1.0M%"},
		{345_789.1234686 / 100., "345.8k%"},
		{45_789.1234686 / 100., "45.8k%"},
		{5_789.1234686 / 100., "5.8k%"},
		{999.999 / 100., "1.0k%"},
		{999.995 / 100., "1.0k%"},

		{999.994 / 100., "1.0k%"},
		{999.99 / 100., "1.0k%"},
		{999.1234686 / 100., "999.1%"},
		{789.1234686 / 100., "789.1%"},
		{89.1234686 / 100., "89.1%"},
		{9.1234686 / 100., "9.1%"},
		{0.1234686 / 100., "0.1%"},

		// NEGATIVE
		{-999_999_999.1234686 / 100., "-1.0B%"},
		{-12_345_789.1234686 / 100., "-12.3M%"},
		{-2_345_789.1234686 / 100., "-2.3M%"},
		{-999_999.4397 / 100., "-1.0M%"},
		{-345_789.1234686 / 100., "-345.8k%"},
		{-45_789.1234686 / 100., "-45.8k%"},
		{-5_789.1234686 / 100., "-5.8k%"},
		{-999.999 / 100., "-1.0k%"},

		{-999.1234686 / 100., "-999.1%"},
		{-789.1234686 / 100., "-789.1%"},
		{-89.1234686 / 100., "-89.1%"},
		{-9.1234686 / 100., "-9.1%"},
		{-0.1234686 / 100., "-0.1%"},

		// infinitesimals + making sure there is no padding with insignificant zeros
		{0.008, "0.8%"},
		{0.005, "0.5%"},

		{0.009, "0.9%"},
		{0.0095 / 100., "9.5e-3%"},

		{0.095 / 100., "0.1%"},

		// Note: .10 IS significant in this case
		{0.001 / 100., "1.0e-3%"},
		{0.00095 / 100., "950.0e-6%"},
		{0.000999999 / 100., "1.0e-3%"},
		{0.00012335234 / 100., "123.4e-6%"},
		{0.000_000_999999 / 100., "1.0e-6%"},
		{0.000_000_02341253 / 100., "23.4e-9%"},
		{0.000_000_000_999999 / 100., "1.0e-9%"},
	}

	for _, tt := range tests {
		t.Run(fmt.Sprintf("%v", tt.input), func(t *testing.T) {
			formatter, err := newPerRangeFormatter(defaultPercentOptions())
			if err != nil {
				t.Errorf("failed: %v", err)
			}
			if got, _ := formatter.StringFormat(tt.input); got != tt.expected {
				t.Errorf("perRangeFormatter.StringFormat(%v) = %v, want %v", tt.input, got, tt.expected)
			}
		})
	}
}
